package com.aracky.system.wxutil;

import com.alibaba.fastjson.JSON;
import com.aracky.common.util.HttpUtil;
import com.aracky.common.util.wxutil.AuthTokenUtil;
import com.aracky.common.util.wxutil.WxUrl;
import com.aracky.system.model.entity.SysDept;
import com.aracky.system.model.entity.SysPost;
import com.aracky.system.model.entity.SysUser;
import com.aracky.system.outside.WxAttr;
import com.aracky.system.outside.WxDept;
import com.aracky.system.outside.WxResp;
import com.aracky.system.outside.WxUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.regex.Pattern;

import static com.aracky.common.constants.RegexConstants.DATE_REGEX;

/**
 * @author zengzhiping
 * @ClassName: WxSyncUtil
 * @Description: 微信同步相关工具
 * @date 2022/07/26 11:08
 */
@Component
@Slf4j
public class WxSyncUtil {

    @Autowired
    private AuthTokenUtil authTokenUtil;


    @Autowired
    private Executor asyncTaskExecutor;

    /**
     * 日期匹配
     */
    private static final Pattern datePattert = Pattern.compile(DATE_REGEX);

    /**
     * 日期格式化
     */
    private static final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-M-d");

    /**
     * 获取微信用户信息
     *
     * @return
     */
    public Map<String, List> getDeptUserList() {
        Map<String, List> resultMap = new HashMap<>(3);

        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        log.info("任务开始:{}", stopWatch.currentTaskName());

        //获取token
        String accessToken = authTokenUtil.getAccessToken();
        //查询部门列表
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("access_token", accessToken);
        String body = HttpUtil.sendGetHttps(WxUrl.DEPTMENT_ID_URL, paramMap);
        WxResp wxResp = JSON.parseObject(body, WxResp.class);
        if (!wxResp.getErrcode().equals(0)) {
            return resultMap;
        }

        List<WxDept> departmentIdList = wxResp.getDepartment_id();
        if (departmentIdList == null || departmentIdList.isEmpty()) {
            return resultMap;
        }

        //这里采用多线程去访问数据
        List<SysDept> sysDeptList = new ArrayList<>(departmentIdList.size());
        SysDept sysDept = null;

        //用户信息
        SysUser sysUser = null;
        List<SysUser> sysUserList = new ArrayList<>(120);

        //岗位信息
        List<SysPost> sysPostList = new ArrayList<>(30);
        SysPost sysPost = null;

        List<CompletableFuture<Void>> completableFutureRes = new ArrayList<>();
        departmentIdList.stream().forEach(wxDept -> {
            //查询部门详细信息
            CompletableFuture<Void> deptTask = CompletableFuture.runAsync(() -> getDeptList(sysDeptList, sysDept, wxDept), asyncTaskExecutor);
            //查询部门下的用户详细信息
            CompletableFuture<Void> userTask = CompletableFuture.runAsync(() -> getUserList(sysUserList, sysPostList, sysPost, sysUser, wxDept), asyncTaskExecutor);
            completableFutureRes.add(deptTask);
            completableFutureRes.add(userTask);
        });

        //等待多线程完成，调用方法处理数据
        CompletableFuture[] completableFutures = completableFutureRes.toArray(new CompletableFuture[completableFutureRes.size()]);
        CompletableFuture.allOf(completableFutures).join();

        stopWatch.stop();
        log.info("任务结束:消耗{}秒", stopWatch.getTotalTimeSeconds());

        //返回数据
        resultMap.put("userList", sysUserList);
        resultMap.put("postList", sysPostList);
        resultMap.put("deptList", sysDeptList);
        return resultMap;

    }

    private void getUserList(List<SysUser> sysUserList, List<SysPost> sysPostList, SysPost sysPost, SysUser sysUser, WxDept wxDept) {
        //获取token
        String accessToken = authTokenUtil.getAccessToken();
        //查询部门列表
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("access_token", accessToken);
        paramMap.put("department_id", wxDept.getId());
        String body = HttpUtil.sendGetHttps(WxUrl.DEPTMENT_USER_DETAIL_URL, paramMap);
        WxResp wxResp = JSON.parseObject(body, WxResp.class);
        if (!wxResp.getErrcode().equals(0)) {
            return;
        }
        List<WxUser> wxUserList = wxResp.getUserlist();
        if (wxUserList == null || wxUserList.isEmpty()) {
            return;
        }
        loopWxUserList(sysUserList, sysPostList, wxDept, wxUserList);
    }

    /**
     * 循环遍历微信用户信息
     *
     * @param sysUserList
     * @param sysPostList
     * @param wxDept
     * @param wxUserList
     */
    private void loopWxUserList(List<SysUser> sysUserList, List<SysPost> sysPostList, WxDept wxDept, List<WxUser> wxUserList) {
        SysUser sysUser;
        SysPost sysPost;
        for (WxUser wxUser : wxUserList) {
            //用户信息
            sysUser = new SysUser();
            sysUser.setDeptId(wxDept.getId());
            sysUser.setLoginName(wxUser.getName());
            sysUser.setUserName(wxUser.getAlias());
            sysUser.setEmail(wxUser.getEmail());
            sysUser.setPhonenumber(wxUser.getMobile());
            sysUser.setSex(Integer.valueOf(wxUser.getGender()) - 1);
            sysUser.setAvatar(wxUser.getAvatar());
            sysUser.setWxUserId(wxUser.getUserid());
            sysUser.setEntryTime(this.getEntryTime(wxUser));
            sysUserList.add(sysUser);
            //岗位信息
            sysPost = new SysPost();
            sysPost.setPostName(wxUser.getPosition());
            sysPost.setDeptId(wxDept.getId());
            sysPost.setWxUserId(wxUser.getUserid());
            sysPostList.add(sysPost);
        }
    }

    /**
     * 获取入职时间
     *
     * @param wxUser
     */
    private LocalDate getEntryTime(WxUser wxUser) {
        // 从企业微信中扩展属性中获取入职时间
        WxAttr wxAttr = wxUser.getExtattr().getAttrs().get(0);
        if (StringUtils.isBlank(wxAttr.getValue())) {
            return null;
        }

        //先验证当前是否是时间
        boolean matches = datePattert.matcher(wxAttr.getValue()).matches();
        if (!matches) {
            return null;
        }

        //进行格式转换为yyyy-MM-dd
        String replace = wxAttr.getValue().replace("/", "-");
        return LocalDate.parse(replace, dateFormatter);
    }


    /**
     * 获取部门信息
     *
     * @param wxDept
     * @return
     */
    public void getDeptList(List<SysDept> sysDeptList, SysDept sysDept, WxDept wxDept) {
        //获取token
        String accessToken = authTokenUtil.getAccessToken();
        //查询部门列表
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("access_token", accessToken);
        paramMap.put("id", wxDept.getId());
        String body = HttpUtil.sendGetHttps(WxUrl.DEPTMENT_DETAIL_URL, paramMap);
        WxResp wxResp = JSON.parseObject(body, WxResp.class);
        if (!wxResp.getErrcode().equals(0)) {
            return;
        }

        WxDept department = wxResp.getDepartment();
        sysDept = new SysDept();
        sysDept.setDeptId(department.getId());
        sysDept.setParentId(department.getParentid());
        sysDept.setDeptName(department.getName());
        sysDept.setOrderNum(String.valueOf(department.getOrder()));
        sysDeptList.add(sysDept);
    }

}
